/******************************************************************************
** 
** File name:	rtos_event_ex.S
** 
** Description:	Event management services. Implementation of 
**				RTOS_TestObjectEvent() and inherited services.
**
** RTOS ver:	3.0
**
** Modules/Functions:
**
**		RTOS_EST_t	RTOS_TestEventISR	( RTOS_EVT_t *  )
**		RTOS_EST_t	RTOS_TestEvent		( RTOS_EVT_t *  )
**		RTOS_EST_t	RTOS_TestTimer		( RTOS_TMR_t *  )
**		RTOS_EST_t	RTOS_TestTaskID		( RTOS_PID_t *  )
**		RTOS_EST_t	RTOS_TestMessageAck	( RTOS_MSG_t *  )
**		RTOS_EST_t	RTOS_TestObjectEvent( RTOS_OBJ_t *  )
**
**  Notes:			This is new version which uses single byte RTOS_EST_t 
**					type (enum) as the return. Previous version used two bytes
**					RtosEvent type as return.
**
*******************************************************************************
** History:
**
** 10/25/2011 -AK- 	Porting to RTOS v.2
** 07/26/2012 -AK- 	RTOS API is downgraded to comply with earliest rtos v2
** 08/08/2012 -AK- 	RTOS source code is checked for byte-by-byte complience 
**					with MPP binary (Dec 8, 2011).
** 09/20/2012 -AK- 	RTOS v3. _ENTER_CRITICAL/_LEAVE_CRITICAL 
**							 _RTOS_PROLOG/_RTOS_EPILOG
** 		
******************************************************************************/
#include        "rtos.inc"

        _MODULE(rtos_event_ex)
		
    _CODESECTION

/******************************************************************************
;; Prototype:	RTOS_EST_t		RTOS_TestObjectEvent	( RTOS_OBJ_t *  )
;;				RTOS_EST_t		RTOS_TestTimer			( RTOS_TMR_t *  )
;;				RTOS_EST_t		RTOS_TestTaskID			( RTOS_PID_t *  )
;;				RTOS_EST_t		RTOS_TestMessageAck		( RTOS_MSG_t *  )
;; Description:	As the standard system objects have an event as their 
;;				second byte. This call test that event. Actually those 
;;				calls are equal to RTOS_TestEvent(pObject->pEvent)
;; Passed:      R25:R24 = Object
;; Returns:		R24 = 0 - _PEND
;;					= 1 - _DONE
;;                  = 2 - something is waiting on it.
;; Uses:        Z, tmp0, tmp1
;; Stack:		TBD
;; Calls:		
;; Assumes:
;; Notes:		1. If event is _DONE, we return _DONE, but reset event to _PEND
;;				2. Alternative return version could be like following:
;; RETURN:  	R25:R24 = 0 - _PEND
;;						= 1 - _DONE
;;                      = 2 - something is waiting on it.
******************************************************************************/

	_FUNCTION(RTOS_TestTimer)
	_PUBLIC(RTOS_TestTaskID)
	_PUBLIC(RTOS_TestMessageAck)
	_PUBLIC(RTOS_TestObjectEvent)

RTOS_TestTimer:
RTOS_TestTaskID:
RTOS_TestMessageAck:
RTOS_TestObjectEvent:

	subi    p1l, lo8(-2)
	sbci    p1h, hi8(-2)

        _ENDFUNC	; _FUNCTION(RTOS_TestObjectEvent)

/******************************************************************************
;; Prototype:	RTOS_EST_t	RTOS_TestEventISR	( RTOS_EVT_t *  )
;;				RTOS_EST_t	RTOS_TestEvent		( RTOS_EVT_t *  )
;; Description:	Non blocking call to check state of the Event. Actually
;;				this is non blocking version of RTOS_WaitEvent().
;; Passed:		R25:R24 = Object
;; Returns:		R24 = 0 - EVT_PEND
;;					= 1 - EVT_DONE
;;					= 2 - EVT_WAIT (something is waiting on it)
;; Uses:		Z, tmp0, tmp1
;; Stack:		TBD
;; Calls:		-
;; Assumes:		-
;; Notes:		1. If event is _DONE, we return _DONE, but reset event 
;;				to EVT_PEND 
;;				2. Alternative return version could be as follows:
;;				= 0 - EVT_PEND
;;				= 1 - EVT_DONE
;;				= 2 - EVT_WAIT ( something is waiting on it )
******************************************************************************/
        _FUNCTION(RTOS_TestEventISR)
        _PUBLIC(RTOS_TestEvent)

RTOS_TestEventISR:
RTOS_TestEvent:

	mov     Zh, p1h
	mov     Zl, p1l
	ldi     p1l, lo8(_DONE)				;; Preload _DONE (1) return
	ldi     p1h, hi8(_DONE)

	_ENTER_CRITICAL						;; Begin critical section (disable all interrupts)
	
	ldd     tmp0, Z+NextL
	ldd     tmp1, Z+NextH
	sub     tmp0, p1l
	sbc     tmp1, p1h

	breq    aits01						;;

	brlo    aits00          			;; if > _DONE return 2
	subi    r1l, lo8(-2)				;; very tricky... = 3
	sbci    r1h, hi8(-2)				;; falls through and decrements.
	
aits00:

	subi    r1l, lo8(1)					;;
	sbci    r1h, hi8(1)     			;; if < _DONE return 0

	_LEAVE_CRITICAL						;; Leave critical section (enable upper level interrupts)

	ret									;; and return

aits01:

	std     Z+NextH, tmp0   	;; Store _PEND (0)
	std     Z+NextL, tmp1   	;; Return _DONE (R25:R24)

	_LEAVE_CRITICAL						;; Leave critical section (enable upper level interrupts)

	ret									;; and return

	_ENDFUNC	;; _FUNCTION(RTOS_TestEvent)

        _END	;; _MODULE(rtos_event_ex)


